#include <iostream>
#include <signal.h>
#include <unistd.h>

using namespace std;

void sigcb(int signo)
{
    cout<<"子进程退出啦，我确实收到了信号"<<signo<<"我是: pid: "<<getpid()<<endl;
}

static void showPending(sigset_t *pendings)
{
    // 一个信号一个信号判断 如果在就打印1 如果不在打印0 
    // 由于屏蔽了40 因此要打印出40个信号 
    for(int sig = 1; sig<= 40;sig++)
    {
        if(sigismember(pendings,sig))
        {
            cout<<"1";
        }
        else
        {
            cout<<"0";
        }
    }
    cout << endl;
}

int main()
{
    //屏蔽2号信号和40号信号
    sigset_t bsig,obsig;
    sigemptyset(&bsig);
    sigemptyset(&obsig);
    //将2号信号和40号信号添加到信号屏蔽字中
    sigaddset(&bsig,2);
    sigaddset(&bsig,40);
    //这是用户级的信号屏蔽字到内核汇总 让当前进程屏蔽到2号和40号信号
    sigprocmask(SIG_SETMASK,&bsig,&obsig);

    //signal
    signal(2,sigcb);
    signal(40,sigcb);
    //1.尝试不断的获取当前进程的pending信号集
    sigset_t pendings;
    while(true)
    {
        // 1.1 清空信号集
        sigemptyset(&pendings);
        
        // 1.2 获取当前进程的pengding信号集
        if(sigpending(&pendings) == 0 )
        {
            // 1.3 打印一下当前进程的pending信号集
            showPending(&pendings);
        }
        sleep(1);
    }
    return 0;
}
// int main()
// {
//     struct sigaction act,oact;
//     act.sa_handler = sigcb;
//     act.sa_flags = 0;

//     sigemptyset(&act.sa_mask);
//     sigaction(SIGINT,&act,&oact);
//     while(true)
//     {
//         cout<<"....................."<<endl;
//         sleep(1);
//     }


//     // signal(SIGINT,handler);
//     // while(true)
//     // {
//     //     cout<<"..................."<<endl;
//     //     sleep(1);
//     // }
//     return 0;
// }

// int main()
// {
//     signal(SIGCHLD,handler);
//     pid_t id = fork();
//     if(id == 0)
//     {
//         //child
//         while(true)
//         {
//             cout<<"我是子进程："<<getpid()<<endl;
//             sleep(1);
//         }
//         exit(0);
//     }

//     //parent
//     while(true)
//     {
//         cout<<"我是父进程："<<getpid()<<endl;
//         sleep(1);
//     }
//     return 0;
// }




// #include <stdio.h>
// #include <signal.h>

// //保持内存的可见性
// volatile int flags = 0;

// void handler(int signo)
// {
//     flags = 1;
//     printf("flags: 0 -> 1\n");
// }

// int main()
// {
//     signal(2,handler);
//     while(!flags);
//     printf("进程是正常退出的! flags: %d \n",flags);
//     return 0;
// }



// #include <iostream>
// #include <unistd.h>
// #include <sys/types.h>
// #include <sys/wait.h>

// using namespace std;

// int cnt = 0;

// void handler(int signo)
// {
//     cout<<"我是一个进程,刚刚获取到了一个信号："<<signo<<"	cnt: "<<cnt<< endl;
//     sigset_t pending;
//     //增加hanlder信号的时间,永远都会正在处理2号信号！
//     while(true)
//     {
//         cout<<"."<<endl;
//         sigpending(&pending);
//         for(int i = 1;i<=31;++i)
//         {
//             if(sigismember(&pending,i))
//                 cout<<'1';
//             else    
//                 cout<<'0';
//         }
//         cout<<endl;
//         sleep(1);
//     }
// }

// static void showPending(sigset_t *pendings)
// {
//     // 一个信号一个信号判断 如果在就打印1 如果不在打印0
//     for(int sig = 1; sig<= 31;sig++)
//     {
//         if(sigismember(pendings,sig))
//         {
//             cout<<"1";
//         }
//         else
//         {
//             cout<<"0";
//         }
//     }
//     cout << endl;
// }


// int main()
// {
//     struct sigaction act,oact;
//     act.sa_handler = handler;
//     act.sa_flags = 0;
//     sigemptyset(&act.sa_mask);

//     sigaction(2,&act,&oact);

//     while(true)
//     {
//         cout<<"main running"<<endl;
//         sleep(1);
//     }

//     return 0;
// }


// int main()
// {
//     cout<<"进程pid:"<<getpid()<<endl;
//     //3.屏蔽2号信号
//     sigset_t bsig,obsig;
//     sigemptyset(&bsig);
//     sigemptyset(&obsig);
//     //3.1添加2号信号到信号屏蔽字中
//     for(int sig = 1;sig<=31;sig++)
//     {
//         sigaddset(&bsig,sig);
//         //2.signal
//         signal(sig,hanlder);
//     }
//     //3.2设置用户级的信号屏蔽字到内核汇总 让当前进程屏蔽到2号信号
//     sigprocmask(SIG_SETMASK,&bsig,&obsig);

//     //1.尝试不断的获取当前进程的pending信号集
//     sigset_t pendings;
//     while(true)
//     {
//         // 1.1 清空信号集
//         sigemptyset(&pendings);
        
//         // 1.2 获取当前进程的pengding信号集
//         if(sigpending(&pendings) == 0 )
//         {
//             // 1.3 打印一下当前进程的pending信号集
//             showPending(&pendings);
//         }
//         sleep(1);
//         cnt++;
//         if(cnt == 10)
//         {
//             //结束信号
//             cout<<"解除对2号信号的block......" <<endl;
//             sigset_t sigs;
//             sigemptyset(&sigs);
//             sigaddset(&sigs,2);
//             sigprocmask(SIG_UNBLOCK,&sigs,nullptr);
            
            
            
//             //cout<<"解除对所有信号的block......" <<endl;
//             //sigprocmask(SIG_SETMASK,&obsig,nullptr);
//         }
//     }
//     return 0;
// }

// int main()
// {
//     //  fork 创建 child process
//     pid_t id = fork();
//     if (id == 0)
//     {
//         // child
//         int *p = nullptr;
//         *p = 1000;
//         //访问野指针

//         exit(1); //退出码设置为1
//     }

//     //父进程阻塞等待
//     int status = 0;
//     waitpid(id,&status,0);
//     printf("exit code:%d, signo : %d , core dump code : %d\n",
//         (status>>8) & 0xFF, status & 0x7F, (status >> 7)&0x1);

//     return 0;
// }



